home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************
- #
- # Shell.c
- #
- # This is a simple application shell that we use to handle the standard mac stuff.
- # In general, the routines in this code should be as generic as possible, and any
- # custom code should be included in CustomApp.c instead.
- #
- # Author: Timothy Carroll
- # Apple Developer Technical Support
- # timc@apple.com
- #
- # Revision: Jason Yeo
- #
- # Modification History:
- #
- # 2/9/97 TMC Initial Release
- #
- # 9/12/97 JY Updated for:
- # TEC 1.2.1
- # Universal Interfaces 3.0
- # CodeWarrior 11 projects
- #
- # Copyright © 1997 Apple Computer, Inc., All Rights Reserved
- #
- #
- # You may incorporate this sample code into your applications without
- # restriction, though the sample code has been provided "AS IS" and the
- # responsibility for its operation is 100% yours. However, what you are
- # not permitted to do is to redistribute the source as "DSC Sample Code"
- # after having made changes. If you're going to re-distribute the source,
- # we require that you make it clear in the source that the code was
- # descended from Apple Sample Code, but that you've made changes.
- #
- *************************************************************************************/
-
- #include "CustomApp.h"
-
-
-
- /*********************************************************************************
- # SHELL GLOBALS
- #
- *********************************************************************************/
- Boolean gQuittingApp;
- Boolean gAppForeGround;
- TPreferences gPreferences;
-
- // UPPs for our standard apple events
- static AEEventHandlerUPP gOpenApp = NULL;
- static AEEventHandlerUPP gOpenDoc = NULL;
- static AEEventHandlerUPP gPrintDoc = NULL;
- static AEEventHandlerUPP gQuitApp = NULL;
-
-
-
-
- void main (void);
- OSStatus InitStandardAEHandlers (void);
- OSStatus TerminateAppStandardAEHandlers (void);
- OSStatus InitAppPreferences (void);
-
-
- void main (void)
- {
- int loop;
- OSStatus theErr = noErr;
-
- EventRecord theEvent;
- UInt32 nextTimeToCheckForEvents = 0;
-
-
- // Expand the heap and set up a block of master pointers
- MaxApplZone();
-
- for (loop = 0; loop < kNumberOfMasters; loop++)
- MoreMasters();
-
- // Standard Mac Init
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- // Initialize standard AppleEvent handlers
- theErr = InitStandardAEHandlers();
- FAIL_OSERR (theErr, "\pError: Failed to initialize event handlers.")
-
- // Initialize the App's custom preferences (from a prefs file perhaps)
- theErr = InitAppPreferences();
- FAIL_OSERR (theErr, "\pError: Failed to load app's preferences")
-
- // Perform custom initialization
- theErr = InitApp();
- FAIL_OSERR (theErr, "\pError: Custom App Initialization failed.")
-
- gQuittingApp = false;
- gAppForeGround = true;
-
- // STANDARD EVENT LOOP
-
- do
- {
- // If the app wants a slice of time, we give it a bit of time to work on stuff.
- // If the app is in the background, it gets one block of time, otherwise we'll
- // keep giving it time until it no longer wants any or when the event interval
- // is up.
-
- // We'll also bail from doing any work if TimeSlice returns an error.
-
- // How's this for a funky loop?! :)
-
- theErr = noErr;
-
- do {}
- while ( AppWantsTime() &&
- ((theErr = TimeSlice()) != noErr) &&
- gAppForeGround &&
- (TickCount() < nextTimeToCheckForEvents));
-
- FAIL_OSERR (theErr, "\pError: TimeSlice returned an error.")
-
- nextTimeToCheckForEvents = TickCount() + kEventInterval;
-
- (void) WaitNextEvent(everyEvent,&theEvent,kSleepTime,NULL);
- theErr = HandleEvent(&theEvent);
- FAIL_OSERR (theErr, "\pError: Event was unable to be handled.")
-
- } while (!gQuittingApp);
-
-
- error:
- cleanup:
- // The shell by default just quits out when an error occurs. A real app should
- // provide some sort of error message.
-
- theErr = TerminateAppStandardAEHandlers ();
-
- theErr = TerminateApp();
-
- return;
- }
-
-
-
- OSStatus InitStandardAEHandlers (void)
- {
- OSStatus theErr = noErr;
-
- // build the UPPs for our standard event handlers
-
- gOpenApp = NewAEEventHandlerProc (HandleOpenAppEvent);
- gOpenDoc = NewAEEventHandlerProc (HandleOpenDocEvent);
- gPrintDoc = NewAEEventHandlerProc (HandlePrintDocEvent);
- gQuitApp = NewAEEventHandlerProc (HandleQuitAppEvent);
-
- // Install the event handlers into the Application's Apple Event table.
-
- theErr = AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,gOpenApp,0,false);
- FAIL_OSERR (theErr, "\pError: Failed to install a core event handler")
-
- theErr = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,gOpenDoc,0,false);
- FAIL_OSERR (theErr, "\pError: Failed to install a core event handler")
-
- theErr = AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,gPrintDoc,0,false);
- FAIL_OSERR (theErr, "\pError: Failed to install a core event handler")
-
- theErr = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,gQuitApp,0,false);
- FAIL_OSERR (theErr, "\pError: Failed to install a core event handler")
-
- // Everything went successfully, we can return without any errors.
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
- cleanup:
- return theErr;
-
- }
-
-
-
- OSStatus TerminateAppStandardAEHandlers (void)
- {
- // Remove the events from the dispatch tables, ignoring any errors
- (void) AERemoveEventHandler(kCoreEventClass,kAEOpenApplication,gOpenApp,false);
- (void) AERemoveEventHandler(kCoreEventClass,kAEOpenDocuments,gOpenDoc,false);
- (void) AERemoveEventHandler(kCoreEventClass,kAEPrintDocuments,gPrintDoc,false);
- (void) AERemoveEventHandler(kCoreEventClass,kAEQuitApplication,gQuitApp,false);
-
- // Dispose of the Routine Descriptors
- if (gOpenApp)
- {
- DisposeRoutineDescriptor (gOpenApp);
- gOpenApp = NULL;
- }
-
- if (gOpenDoc)
- {
- DisposeRoutineDescriptor (gOpenDoc);
- gOpenDoc = NULL;
- }
-
- if (gPrintDoc)
- {
- DisposeRoutineDescriptor (gPrintDoc);
- gPrintDoc = NULL;
- }
-
- if (gQuitApp)
- {
- DisposeRoutineDescriptor (gQuitApp);
- gQuitApp = NULL;
- }
-
- return noErr;
- }
-
-
- // We use OSErr instead of OSStatus because this can be returned by an AppleEvent
- OSErr CheckAppleEventForMissingParams(AppleEvent *event)
- {
- OSErr theErr = noErr;
- Size actualSize;
- DescType returnedType;
-
- theErr = AEGetAttributePtr(event,keyMissedKeywordAttr,typeWildCard, &returnedType,nil,0,&actualSize);
-
- // If we found a missing parameter, we should ignore this event.
- if (theErr == noErr)
- theErr = errAEEventNotHandled;
- // Otherwise, if we couldn't find a missing attribute, the event should be handled.
- else if (theErr == errAEDescNotFound)
- theErr = noErr;
-
- return theErr;
- }
-
- OSStatus DispatchQuitEvent (void)
- {
- // create a quit event and dispatch it to ourself.
-
- OSStatus theErr = noErr;
- AppleEvent quitEvent, quitReply;
- ProcessSerialNumber process;
- AEAddressDesc address;
-
- quitEvent.dataHandle = NULL;
- address.dataHandle = NULL;
-
- // Create a descriptor for us
- process.highLongOfPSN = 0;
- process.lowLongOfPSN = kCurrentProcess;
-
- theErr = AECreateDesc (typeProcessSerialNumber, (Ptr)&process, sizeof (process), &address);
- FAIL_OSERR (theErr, "\pError: Failed to create a process descriptor")
-
- // Create the quit event
- theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &address,
- kAutoGenerateReturnID, kAnyTransactionID, &quitEvent);
- FAIL_OSERR (theErr, "\pError: Failed to generate the quit AppleEvent")
-
- // Dispatch the event
- theErr = AESend (&quitEvent, &quitReply, kAENoReply+kAEAlwaysInteract,
- kAENormalPriority, kAEDefaultTimeout, nil, nil);
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
- cleanup:
-
- if (quitEvent.dataHandle)
- (void) AEDisposeDesc (&quitEvent);
- if (address.dataHandle)
- (void) AEDisposeDesc (&address);
-
- return theErr;
- }
-
- OSStatus InitAppPreferences (void)
- {
- OSStatus theErr = noErr;
-
- theErr = ReadPreferencesFile(&gPreferences);
- if (theErr == noErr)
- goto cleanup;
-
- // We either have a corrupted prefs or it didn't exist. Restore to default
- // prefs and save out a new file.
-
- theErr = SetDefaultPreferences(&gPreferences);
- FAIL_OSERR (theErr, "\pError: Failed to set default prefs for the app");
-
- theErr = WritePreferencesFile (&gPreferences);
- FAIL_OSERR (theErr, "\pError: Unable to write a prefs file");
-
- goto cleanup;
-
- error:
- if (theErr == noErr)
- theErr = paramErr;
-
- cleanup:
- return theErr;
- }